package com.hl.card.modular.pack.service.impl;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

import javax.annotation.Resource;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.hl.card.common.util.HttpClientTool;
import com.hl.card.common.util.PayDigestUtil;
import com.hl.card.modular.pack.service.*;
import com.hl.card.modular.system.service.ISysDicService;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Hash;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.hl.card.common.constant.factory.PageFactory;
import com.hl.card.common.constant.tips.SuccessTip;
import com.hl.card.common.persistence.model.Recharge;
import com.hl.card.common.util.ResponseObject;
import com.hl.card.core.shiro.ShiroKit;
import com.hl.card.core.support.BeanKit;
import com.hl.card.modular.pack.dao.RechargeMapper;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

/**
 * <p>
 * 充值记录 服务实现类
 * </p>
 *
 * @author huangpu
 * @since 2018-08-13
 */
@Service
public class RechargeServiceImpl extends ServiceImpl<RechargeMapper, Recharge> implements RechargeService {

	private Logger logger= LoggerFactory.getLogger(RechargeService.class);
	@Value("${pay.config.baseUrl}")
	private String baseUrl;
	@Value("${pay.config.mchInfo}")
	private String mchInfo;

	@Value("${pay.config.payChanel}")
	private String payChanel;

	@Value("${pay.config.reqKey}")
	private String reqKey;

	@Value("${pay.config.trade}")
	private String trade;

	@Value("${pay.config.cardUrl}")
	private String cardUrl;

	@Value("${pay.config.cardBlance}")
	private String cardBalance;

	@Value("${pay.config.doTrans}")
	private String doTrans;

	@Value("${pay.config.mchId}")
	private String mchId;

	@Autowired
	private DoTrans confirmTrans;

    @Autowired
    private RechargePayMgrService rechargePayMgrService;

    //远程服务
    @Autowired
    private RechargePaymentService rechargePaymentService;
    
	@Resource(name="rechargeMapper")
	private RechargeMapper rechargeMapper;

	@Autowired
	private TokenWallet tokenWallet;

	@Autowired
	private RechargeService rechargeService;

	@Autowired
	ISysDicService sysDicService;

	@Autowired
	private RedisTemplate<String, String> redisTemplate;

	@Override
	public Recharge selectMultiConditionOne(Recharge recharge) {
		return rechargeMapper.selectMultiConditionOne(recharge);
	}
	@Override
	public int auditing(Recharge recharge) {
		return rechargeMapper.auditing(recharge);
	}
	
	@Override
	public Object doc(Recharge recharge) {
		Recharge tempRecharge= selectById(recharge.getRecharge_no());
		SuccessTip su = new SuccessTip();
    	if (tempRecharge==null) {//无数据 可以跟单
    		JSONObject json = new JSONObject();
        	json.put("mchTransNo", recharge.getRecharge_no());
        	String data = rechargePayMgrService.getList(json.toJSONString(), 1, 1);
        	ResponseObject object = JSONObject.parseObject(data, ResponseObject.class);
        	List<Map<String, Object>> objectList = JSONObject.parseObject(object.getData()+"", List.class);
        	Map<String, Object> rechargeInfomap = objectList.get(0);
        	if (rechargeInfomap!=null) {
        		recharge.setAmount(Double.valueOf(rechargeInfomap.get("amount")+""));
        		recharge.setAdd_time(new Date(Long.valueOf(rechargeInfomap.get("createTime")+"")));
        		recharge.setCurrency((String)rechargeInfomap.get("currency"));
        		recharge.setRecharge_no((String)rechargeInfomap.get("mchTransNo"));
        		recharge.setRemarkInfo((String)rechargeInfomap.get("remarkInfo"));
        		recharge.setStatus(Integer.valueOf(rechargeInfomap.get("status")+""));
        		if (StringUtils.isNumeric(rechargeInfomap.get("param1")+"")) {
        			recharge.setConsume(Double.valueOf(rechargeInfomap.get("param1")+""));
				}
        		recharge.setTrans_order_id((String)rechargeInfomap.get("transOrderId"));
        		recharge.setDoc_time(new Date());
        		recharge.setDoc_account(ShiroKit.getUser().getAccount());
        		recharge.insert();
			}
        	return su;

		}else if(tempRecharge.getDoc_account()==null){//有数据 并且可以跟单
    		recharge.setDoc_time(new Date());
    		recharge.setDoc_account(ShiroKit.getUser().getAccount());
			recharge.setStatus(2);
			rechargeMapper.update(recharge);
			ResponseObject tokre = tokenWallet.checkInnerTrans(recharge.getRecharge_no());
			JSONObject jo=JSON.parseObject(tokre.getData().toString());
			if(jo.get("type").equals("outside")){

			}else if(jo.get("type").equals("inner")){
				String transOrderId=String.valueOf(jo.get("transOrderId"));
				String rechargeString=String.valueOf(jo.get("recharge"));
				if(rechargeString.equals("ignore")){
				}else if(rechargeString.equals("fail")){
					recharge.setStatus(6);
					recharge.setTrans_order_id(transOrderId);
					rechargeMapper.update(recharge);
				}else if(rechargeString.equals("success")){
					Recharge rechargeSelect= new Recharge();
					rechargeSelect.setRecharge_no(recharge.getRecharge_no());
					rechargeSelect.setDoc_account(ShiroKit.getUser().getAccount());
					Recharge tmRecharge= rechargeService.selectMultiConditionOne(rechargeSelect);
					if (tempRecharge==null || tempRecharge.getStatus()==3) {
						su.setMessage("无法操作");
						su.setCode(2);
					}else {
						JSONObject json = new JSONObject();
						json.put("mchTransNo", recharge.getRecharge_no());
						JSONObject resObj = rechargeService.confirmTrans(tmRecharge);
						if ("SUCCESS".equals(resObj.getString("retCode")) && "SUCCESS".equalsIgnoreCase(resObj.getString("resCode").toString())) {
							recharge.setAudit_time(new Date());
							recharge.setStatus(4);
							recharge.setTrans_order_id(jo.getString("transOrderId"));
							recharge.setConfirm_transfer_time(recharge.getConfirm_transfer_time());
							recharge.setMiner(recharge.getMiner());
							rechargeService.auditing(recharge);
						} else {
							su.setMessage("操作失败");
							su.setCode(2);
						}
					}
				}
			}
			return su;
		}else {//有数据 并且不可以跟单
			su.setMessage("无法跟单");
			su.setCode(2);
			return su;
		}
	}
	/**
	 * 对此方法进行改造
	 * @param recharge
	 * @return
	 */
	@Override
	public Page<Recharge> selectMultiCondition(Recharge recharge) {
		     Page<Recharge> page = new PageFactory<Recharge>().defaultPage();
	    	 Wrapper<Recharge> wrapper = new EntityWrapper<>();
	    	 wrapper.orderBy("add_time",false);
		     if (recharge.getAdd_time()!=null &&  recharge.getAdd_time_end()!=null) {
	    		 wrapper.between("add_time", recharge.getAdd_time(), recharge.getAdd_time_end());
			}
	    	 if (recharge.getDoc_account()!=null) {
	    		 wrapper.eq("doc_account", recharge.getDoc_account());
			}
	    	 if (recharge.getStatus()!=null) {
	    		 wrapper.eq("status", recharge.getStatus());
	    	 }
	    	 if (recharge.getBinding_phone()!=null) {
	    		 wrapper.eq("binding_phone", recharge.getBinding_phone());
	    	 }
	    	 if (recharge.getUser_id()!=null) {
					wrapper.eq("user_id", recharge.getUser_id());
	    	 }
	    	 if (recharge.getExtra()!=null) {
					wrapper.eq("extra", recharge.getExtra());
	    	 }
	    	 if(recharge.getExtra().equals("RECHARGE")){
	    	 }
			Page<Recharge> dPage = selectPage(page, wrapper);
			return dPage;
		}
	public Map<String, Object> select(Recharge recharge) {
    	recharge.setDoc_account(ShiroKit.getUser().getAccount());
		Recharge tempRecharge=selectById(recharge.getRecharge_no());
    	String statusStr="";
    	switch(tempRecharge.getStatus())
		{
		case 0:
			statusStr="待转账";
			break;
		case 1:
			statusStr="已转账，待审核";
		  break;
		case 2:
			statusStr="已完成";
		  break;
		case 3:
			statusStr="已取消";
			break;
		default:
			statusStr =tempRecharge.getStatus()+"";
		}
    	 Map<String, Object> map =BeanKit.beanToMap(tempRecharge);
    	 map.put("status", statusStr);
		return map;
	}
	@Override
	public Page<Recharge> selectMultiConditionLimit(Recharge recharge, Integer size, Integer current) {
		Page<Recharge> page = new Page<>(current, size);
		Wrapper<Recharge> wrapper = new EntityWrapper<Recharge>();
		wrapper.orderBy("add_time",false);
		if (recharge.getAdd_time()!=null &&  recharge.getAdd_time_end()!=null) {
			wrapper.between("add_time", recharge.getAdd_time(), recharge.getAdd_time_end());
		}
		if (recharge.getDoc_account()!=null) {
			wrapper.eq("doc_account", recharge.getDoc_account());
		}
		if (recharge.getStatus()!=null) {
			wrapper.eq("status", recharge.getStatus());
		}
		if (recharge.getBinding_phone()!=null) {
			wrapper.eq("binding_phone", recharge.getBinding_phone());
		}
		if (recharge.getUser_id()!=null) {
			wrapper.eq("user_id", recharge.getUser_id());
		}
		if (recharge.getExtra()!=null) {
			wrapper.eq("extra", recharge.getExtra());
		}
		Page<Recharge> dPage = selectPage(page, wrapper);
		return dPage;
	}

	public void cancel(){
		HashMap<String, Object> map = new HashMap<>();
		map.put("extra","RECHARGE");
		map.put("status","1");
		List<Recharge> recharges=this.selectByMap(map);
		for(Recharge recharge:recharges){
			String  no=recharge.getRecharge_no();
			Recharge redisRecharge=getRedisRechargeById(no);
			if(redisRecharge==null){
				recharge.setStatus(3);//取消此订单
				this.updateById(recharge);
			}
		}
	};
	//通过远程接口调用
	public Recharge getRedisRechargeById(String key){
		String reString=rechargePaymentService.getRedis(key);
		Recharge recharge=JSONObject.parseObject(reString,Recharge.class);
		return recharge;
	}
	public JSONObject confirmTrans(Recharge recharge){
		String mchTransNo=recharge.getRecharge_no();
		JSONObject paramMap = new  JSONObject();
		paramMap.put("mchId", mchId);
		paramMap.put("mchTransNo", mchTransNo);
		String reqSign = PayDigestUtil.getSign(paramMap, reqKey);
		paramMap.put("sign", reqSign);
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
		System.out.println(paramMap.toJSONString());
		String str = confirmTrans.confirm(paramMap.toJSONString());
		return JSONObject.parseObject(str);
	}

	@Override
	public String getEthReal() {
		List<Map<String, Object>> list = sysDicService.selectListByCode("ETHPZ");
		logger.info("ETHPZ:"+list.size());
		Double rate = 1.0;
		if(list != null) {
			String value = (String) list.get(0).get("dicValue");
			if(StringUtils.isNotBlank(value)) {
				try {
					rate = Double.parseDouble(value);
				} catch (NumberFormatException e) {
					e.printStackTrace();
				}
			}
		}
		logger.info("rate:"+rate);
		System.out.println("rate:"+rate);
		String  price="0";
		String resp =HttpClientTool.doGetSSL("https://api.feixiaohao.com/site/headercoinlist#",null,"utf-8");
		logger.info("resp:"+resp);
		Optional<JSONObject> jso=Optional.empty();
		if(resp!=null){
			JSONObject jo = JSON.parseObject(resp);
			List<JSONObject> ja= JSONArray.parseArray(jo.get("content").toString(),JSONObject.class);
			jso = ja.stream().filter(coin -> coin.get("CoinCode").equals("ethereum")).findFirst();
		logger.info("eth 实时价格获取成功！");
		}
		ListOperations<String, String> vo = redisTemplate.opsForList();
		String	hisPriceStr=vo.index("ethPrice", 0);
		Double hisPrice=0d;
		if(hisPriceStr!=null){
			hisPrice=Double.parseDouble(hisPriceStr);
		}
		System.out.println("hisPrice"+hisPrice);
		if(jso.isPresent()){
			price=jso.get().get("Price_Cny").toString();
			Double dPrice=Double.parseDouble(price);
			Double	ratePrice=dPrice*(1-rate);
			if(ratePrice>(hisPrice*1.01)||dPrice<hisPrice){
				vo.leftPush("ethPrice", ratePrice.toString());
				price=dPrice.toString();
			}else{
				price=hisPriceStr;
			}
		}
		if(price.equals("0")){
			price=vo.index("ethPrice", 0);
		}
		return price;
	}
	@Override
	public String getEthRealHtml() {
		List<Map<String, Object>> list = sysDicService.selectListByCode("ETHPZ");
		logger.info("ETHPZ:"+list.size());
		Double rate = 1.0;
		if(list != null) {
			String value = (String) list.get(0).get("dicValue");
			if(StringUtils.isNotBlank(value)) {
				try {
					rate = Double.parseDouble(value);
				} catch (NumberFormatException e) {
					e.printStackTrace();
				}
			}
		}
		logger.info("rate:"+rate);
		String  price="0";
		try {
			Document doc = Jsoup.connect("https://www.feixiaohao.com/currencies/ethereum/").get();
			Elements newsHeadlines = doc.select(".mainPrice .convert");
			for (Element headline : newsHeadlines) {
				price=headline.text();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		ListOperations<String, String> vo = redisTemplate.opsForList();
		String	hisPriceStr=vo.index("ethPrice", 0);
		Double hisPrice=0d;
		if(hisPriceStr!=null){
			hisPrice=Double.parseDouble(hisPriceStr);
		}
		if(!price.equals("0")){
			Double dPrice=Double.parseDouble(price);
			Double	ratePrice=dPrice*(1-rate);
			if(ratePrice>(hisPrice*1.01)||dPrice<hisPrice){
				vo.leftPush("ethPrice", ratePrice.toString());
				price=dPrice.toString();
			}else{
				price=hisPriceStr;
			}
		}else{
			price=vo.index("ethPrice", 0);
		}
		return price;
	}
	@Override
	public String getGUSDReal() {
		String real="0";
		String price="0";
		try {
			Document doc = Jsoup.connect("https://www.feixiaohao.com/currencies/geminidollar/").get();
			logger.info(doc.title());
			Elements newsHeadlines = doc.select(".mainPrice .convert");
			for (Element headline : newsHeadlines) {
				real=headline.text();
			}
		} catch (IOException e) {
			logger.info("GUSD 汇率获取失败");
			logger.info(e.getMessage());
			e.printStackTrace();
		}
		ListOperations<String, String> vo = redisTemplate.opsForList();
		String	hisPriceStr=vo.index("gusdPrice", 0);
		if(hisPriceStr==null){
			hisPriceStr="0";
		}
		if(!real.equals("0")){
			vo.leftPush("gusdPrice", real);
			price=real;
		}else{
			price=hisPriceStr;
		}
		return price;
	}
}
